package de.juwimm.cms.gui.tree; import static de.juwimm.cms.client.beans.Application.getBean; import java.awt.Insets; import java.awt.Point; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.dnd.Autoscroll; import java.awt.dnd.DnDConstants; import java.awt.dnd.DragGestureEvent; import java.awt.dnd.DragGestureListener; import java.awt.dnd.DragSource; import java.awt.dnd.DragSourceContext; import java.awt.dnd.DragSourceDragEvent; import java.awt.dnd.DragSourceDropEvent; import java.awt.dnd.DragSourceEvent; import java.awt.dnd.DragSourceListener; import java.awt.dnd.DropTarget; import java.awt.dnd.DropTargetDragEvent; import java.awt.dnd.DropTargetDropEvent; import java.awt.dnd.DropTargetEvent; import java.awt.dnd.DropTargetListener; import java.io.IOException; import javax.swing.JTree; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; import org.apache.log4j.Logger; import de.juwimm.cms.client.beans.Beans; import de.juwimm.cms.common.Constants; import de.juwimm.cms.util.Communication; import de.juwimm.cms.vo.ViewComponentValue; public class DnDTree extends JTree implements Autoscroll { /** */ private static final long serialVersionUID = 1L; private final Communication comm = ((Communication) getBean(Beans.COMMUNICATION)); private static Logger log = Logger.getLogger(DnDTree.class); private Insets insets; private int top = 0, bottom = 0, topRow = 0, bottomRow = 0; public DnDTree() { DragSource dragSource = DragSource.getDefaultDragSource(); dragSource.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY_OR_MOVE, new TreeDragGestureListener()); DropTarget dropTarget = new DropTarget(this, new TreeDropTargetListener()); } public DnDTree(TreeModel model) { super(model); DragSource dragSource = DragSource.getDefaultDragSource(); dragSource.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY_OR_MOVE, new TreeDragGestureListener()); DropTarget dropTarget = new DropTarget(this, new TreeDropTargetListener()); } public Insets getAutoscrollInsets() { return insets; } public void autoscroll(Point p) { // Only support up/down scrolling top = Math.abs(getLocation().y) + 10; bottom = top + getParent().getHeight() - 20; int next; if (p.y < top) { next = topRow--; bottomRow++; scrollRowToVisible(next); } else if (p.y > bottom) { next = bottomRow++; topRow--; scrollRowToVisible(next); } } private static class TreeDragGestureListener implements DragGestureListener { public void dragGestureRecognized(DragGestureEvent dragGestureEvent) { // Can only drag leafs JTree tree = (JTree) dragGestureEvent.getComponent(); TreePath path = tree.getSelectionPath(); if (path != null) { TreeNode selection = (TreeNode) tree.getLastSelectedPathComponent(); PageNode entry = (PageNode) tree.getLastSelectedPathComponent(); Integer viewComponentId = entry.getViewComponent().getViewComponentId(); if (viewComponentId != null) { TransferableDataNode node = new TransferableDataNode(viewComponentId); dragGestureEvent.startDrag(DragSource.DefaultCopyDrop, node, new MyDragSourceListener()); } } } } private class TreeDropTargetListener implements DropTargetListener { public void dragEnter(DropTargetDragEvent dropTargetDragEvent) { // Setup positioning info for auto-scrolling top = Math.abs(getLocation().y); bottom = top + getParent().getHeight(); topRow = getClosestRowForLocation(0, top); bottomRow = getClosestRowForLocation(0, bottom); insets = new Insets(top + 10, 0, bottom - 10, getWidth()); } public void dragExit(DropTargetEvent dropTargetEvent) { } public void dragOver(DropTargetDragEvent dropTargetDragEvent) { } public void dropActionChanged(DropTargetDragEvent dropTargetDragEvent) { } public synchronized void drop(DropTargetDropEvent dropTargetDropEvent) { Point location = dropTargetDropEvent.getLocation(); TreePath path = getPathForLocation(location.x, location.y); Object node = path.getLastPathComponent(); if ((node != null) && (node instanceof TreeNode) && (node instanceof PageNode)) { try { Transferable tr = dropTargetDropEvent.getTransferable(); if (tr != null) { dropTargetDropEvent.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); Object viewcomponentId = tr.getTransferData(DataFlavor.stringFlavor); /**Drop the element to parent*/ dropNodeToParent((PageNode) node, Integer.parseInt(viewcomponentId.toString())); dropTargetDropEvent.dropComplete(true); System.out.println("Node transfered " + viewcomponentId); } else { System.err.println("Rejected"); dropTargetDropEvent.rejectDrop(); } } catch (IOException io) { io.printStackTrace(); dropTargetDropEvent.rejectDrop(); } catch (UnsupportedFlavorException ufe) { ufe.printStackTrace(); dropTargetDropEvent.rejectDrop(); } } else { System.out.println("Can't drop here"); dropTargetDropEvent.rejectDrop(); } } /** * Drop the node to parent and refresh the tree * @param parent * @param viewComponentId */ private void dropNodeToParent(PageNode entry, Integer viewComponentId) { /**copy to new parent and delete from old one*/ //ViewComponentValue[] viewComponentArray = comm.copyViewComponentToParent(entry.getViewComponent().getViewComponentId(), new Integer[] {viewComponentId}, ViewComponentEvent.MOVE_LEFT); ViewComponentValue[] viewComponentArray = null; ViewComponentValue viewComponentValue = null; try { viewComponentValue = comm.getViewComponent(viewComponentId); viewComponentArray = new ViewComponentValue[] {viewComponentValue}; } catch (Exception e) { if (log.isDebugEnabled()) { log.debug("Error in dropNodeToParent ", e); } } //comm.getViewComponent4Unit(treeSelectionEventData.getUnitId(), -1); CmsTreeModel treeModel = new CmsTreeModel(new PageContentNode(viewComponentValue)); DnDTree.this.setModel(treeModel); for (ViewComponentValue viewComponent : viewComponentArray) { PageNode temp = null; switch (viewComponent.getViewType()) { case Constants.VIEW_TYPE_EXTERNAL_LINK: temp = new PageExternallinkNode(viewComponent, treeModel); break; case Constants.VIEW_TYPE_INTERNAL_LINK: temp = new PageInternallinkNode(viewComponent, treeModel); break; case Constants.VIEW_TYPE_SYMLINK: temp = new PageSymlinkNode(viewComponent, treeModel); break; case Constants.VIEW_TYPE_SEPARATOR: temp = new PageSeparatorNode(viewComponent, treeModel); break; default: temp = new PageContentNode(viewComponent, treeModel); break; } entry.insert(temp, 0); } treeModel.nodeStructureChanged(entry); } //private void addElement(TreePath path, Object element) { /** add new subnode to drop_node, update viewComponent */ //PageNode entry = (PageNode)DnDTree.this.getLastSelectedPathComponent(); ///TreeNode node = new TreeNode(); //System.out.println("Added: " + node + " to " + parent); //TreeModel model = (TreeModel) (DnDTree.this.getModel()); //((DefaultTreeModel) model).insertNodeInto(node, parent, parent.getChildCount()); ddd //} } private static class MyDragSourceListener implements DragSourceListener { public void dragDropEnd(DragSourceDropEvent dragSourceDropEvent) { if (dragSourceDropEvent.getDropSuccess()) { int dropAction = dragSourceDropEvent.getDropAction(); if (dropAction == DnDConstants.ACTION_MOVE) { System.out.println("MOVE: remove node"); } } } public void dragEnter(DragSourceDragEvent dragSourceDragEvent) { DragSourceContext context = dragSourceDragEvent.getDragSourceContext(); int dropAction = dragSourceDragEvent.getDropAction(); if ((dropAction & DnDConstants.ACTION_COPY) != 0) { context.setCursor(DragSource.DefaultCopyDrop); } else if ((dropAction & DnDConstants.ACTION_MOVE) != 0) { context.setCursor(DragSource.DefaultMoveDrop); } else { context.setCursor(DragSource.DefaultCopyNoDrop); } } public void dragExit(DragSourceEvent dragSourceEvent) { } public void dragOver(DragSourceDragEvent dragSourceDragEvent) { } public void dropActionChanged(DragSourceDragEvent dragSourceDragEvent) { } } } class TransferableDataNode implements Transferable { private Integer data; public TransferableDataNode(Integer data) { this.data = data; } public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { Object returnObject = null; if (flavor.equals(DataFlavor.stringFlavor)) { Object userObject = data; if (userObject == null) { returnObject = data.toString(); } else { returnObject = userObject.toString(); } } return returnObject; } public DataFlavor[] getTransferDataFlavors() { return new DataFlavor[] {DataFlavor.stringFlavor}; } public boolean isDataFlavorSupported(DataFlavor flavor) { if (flavor.equals(DataFlavor.stringFlavor)) { return true; } return false; } }